package com.eds.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.codingapi.txlcn.tc.annotation.TccTransaction;
import com.eds.dao.RedisDao;
import com.eds.dto.*;
import com.eds.exception.BusException;
import com.eds.feign.OrderFeign;
import com.eds.feign.OssFeign;
import com.eds.feign.UserService;
import com.eds.log.LogUtil;
import com.eds.mapper.CourseBookingMapper;
import com.eds.mapper.CourseMapper;
import com.eds.mapper.OssImageMapper;
import com.eds.pojo.BaseResult;
import com.eds.pojo.CodeEnum;
import com.eds.pojo.CourseTableDTO;
import com.eds.service.CourseService;
import com.eds.utils.DateTimeUtils;
import com.eds.utils.SnowflakeIdGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pojo.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author 34195
 * @description 针对表【course】的数据库操作Service实现
 * @createDate 2025-03-21 11:10:41
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course>
        implements CourseService {
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private OssImageMapper ossImageMapper;
    @Autowired
    private OssFeign ossFeign;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SnowflakeIdGenerator idGenerator;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private CourseBookingMapper courseBookingMapper;
    @Autowired
    private RedisDao<Object> redisDao;
    @Autowired
    private OrderFeign orderFeign;


    /* *
     * @Title: selectAllCourse
     * @Author: vvSmile
     * @Date: 2025-03-21 18:20:46
     * @param currentPage
     * @param pageSize
     * @return Page<Course>
     * @Description: TODO 分页查询所有的课程信息
     */
    @Override
    public PageUtils<Course> selectAllCourseService(int currentPage, int pageSize) {
        try {
            // 1. 查询总记录数
            QueryWrapper<Course> countWrapper = new QueryWrapper<>();
            countWrapper.eq("status", 1);
            long total = courseMapper.selectCount(countWrapper);

            // 2. 计算分页参数
            long offset = (currentPage - 1) * pageSize;

            // 3. 查询当前页数据
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                    .orderByDesc("create_time")  // 按创建时间倒序
                    .last("LIMIT " + offset + "," + pageSize);  // 使用MySQL的LIMIT语句

            List<Course> records = courseMapper.selectList(queryWrapper);

            // 4. 构建分页对象
            return new PageUtils<>(records, total, pageSize, currentPage);

        } catch (Exception e) {
            throw new BusException(
                    CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getCode(),
                    "查询课程列表失败：" + e.getMessage()
            );
        }

    }

    /* *
     * @Title: selectCourseByName
     * @Author: vvSmile
     * @Date: 2025-03-21 18:21:04
     * @param currentPage
     * @param pageSize
     * @param name
     * @return Page<Course>
     * @Description: TODO 通过课程名分页查询课程的信息
     */
    @Override
    public Page<Course> selectCourseByNameService(int currentPage, int pageSize, String name) {
        //开启分页
        Page<Course> page = new Page<>(currentPage, pageSize);
        //创建QueryWrapper对象，配置查询条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //配置查询条件
        queryWrapper.eq("title", name);
        //调用mapper层查询所有课程
        Page<Course> coursePage = courseMapper.selectPage(page, queryWrapper);
        if (coursePage == null) {
            throw new BusException(CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getCode(), CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getMessage());
        }
        //返回结果
        return coursePage;

    }

    /* *
     * @Title: selectCourseById
     * @Author: vvSmile
     * @Date: 2025-03-21 18:21:37
     * @param currentPage
     * @param pageSize
     * @param courseId
     * @return Page<Course>
     * @Description: TODO 通过老师ID查询课程的信息
     */
    @Override
    public Page<Course> selectCourseByTeacherIdService(int currentPage, int pageSize, Long teacherId) {
        //开启分页
        Page<Course> page = new Page<>(currentPage, pageSize);
        //创建QueryWrapper对象，配置查询条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //配置查询条件
        queryWrapper.eq("teacher_id", teacherId);
        //调用mapper层查询所有课程
        Page<Course> coursePage = courseMapper.selectPage(page, queryWrapper);
        if (coursePage == null) {
            throw new BusException(CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getCode(), CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getMessage());
        }
        //返回结果
        return coursePage;
    }

    /* *
     * @Title: selectCourseByCourseId
     * @Author: vvSmile
     * @Date: 2025-03-21 19:06:57
     * @param currentPage
     * @param pageSize
     * @param courseId
     * @return Course
     * @Description: TODO 根据课程Id查课程信息
     */
    @Override
    public Course selectCourseByCourseIdService(Long courseId) {
        //创建QueryWrapper对象，配置查询条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //配置查询条件
        queryWrapper.eq("course_id", courseId);
        //调用mapper层查询所有课程
        Course course = courseMapper.selectOne(queryWrapper);
        if (course == null) {
            throw new BusException(CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getCode(), CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getMessage());
        }

        //根据CourseId查询TeacherSchedule
        List<TeacherSchedule> teacherSchedules = userService.selectTeacherSchedules(course.getCourseId());
        if (teacherSchedules == null) {
            throw new BusException(CodeEnum.SELECT_COURSE_SCHEDULE_INFO_BY_COURSE_ID_ERROR.getCode(), CodeEnum.SELECT_COURSE_SCHEDULE_INFO_BY_COURSE_ID_ERROR.getMessage());
        }
        course.setTeacherSchedule(teacherSchedules);
        return course;
    }


    /* *
     * @Title: selectCourseByToken
     * @Author: vvSmile
     * @Date: 2025-03-28 10:02:45
     * @param token
     * @return List<Course>
     * @Description: TODO 根据Token查课程信息
     */
    @Override
    public List<Course> selectCourseByToken(String token) {
        //根据token获取userId
        Long teacherIdFromToken = userService.getUserIdFromToken(token);
        if (teacherIdFromToken == 0) {
            throw new BusException(CodeEnum.GET_USERID_BY_TOKEN.getCode(), CodeEnum.GET_USERID_BY_TOKEN.getMessage());
        }
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.eq("teacher_id", teacherIdFromToken);
        List<Course> courses = courseMapper.selectList(courseQueryWrapper);
        if (courses == null) {
            throw new BusException(CodeEnum.SELECT_COURSE_INFO_BY_TEACHER_ID_ERROR.getCode(), CodeEnum.SELECT_COURSE_INFO_BY_TEACHER_ID_ERROR.getMessage());
        }
        return courses;
    }

    /* *
     * @Title: selectTeacherInfo
     * @Author: vvSmile
     * @Date: 2025-03-24 19:21:59
     * @param courseId
     * @return Course
     * @Description: TODO 通过课程ID查看老师信息
     */
    @Override
    public User selectTeacherInfo(Long courseId) {
        //创建QueryWrapper对象，配置查询条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //配置查询条件
        queryWrapper.eq("course_id", courseId);
        //调用mapper层查询所有课程
        Course course = courseMapper.selectOne(queryWrapper);
        if (course == null) {
            throw new BusException(CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getCode(), CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getMessage());
        }
        User user = userService.getUserInfoByTeacherId(course.getTeacherId());
        if (user == null) {
            throw new BusException(CodeEnum.SELECT_USER_INFO_BY_USERID_ERROR.getCode(), CodeEnum.SELECT_USER_INFO_BY_USERID_ERROR.getMessage());
        }
        User user1 = new User();
        user1.setUserName(user.getUserName());
        user1.setEducation(user.getEducation());
        user1.setOssImages(user.getOssImages());
        user1.setSchool(user.getSchool());
        user1.setGender(user.getGender());
        user1.setTeacher(user.getTeacher());
        return user1;
    }


    /* *
     * @Title: insertCourseService
     * @Author: vvSmile
     * @Date: 2025-03-22 19:41:30
     * @param token
     * @param courCreateRequest
     * @return Boolean
     * @Description: TODO 添加课程（同时处理课程信息和图片上传，要么全部成功，要么全部回滚。
     *                因此，必须将这两个步骤解耦，通过异步消息队列来实现。课程信息先保存为pending状态，
     *              然后发送消息到RabbitMQ，由消费者异步处理图片上传。如果图片上传成功，更新课程状态为
     *              active；如果失败，则回滚删除课程和已上传的图片。）*/
    @Transactional(rollbackFor = Exception.class)
    @Override
    @LcnTransaction
    public BaseResult insertCourseService(String token, CourCreateRequest courCreateRequest) throws Exception {
        try {
            //查询用户id
            Long userIdFromToken = userService.getUserIdFromToken(token);
            if (userIdFromToken == 0) {
                throw new BusException(CodeEnum.GET_USERID_BY_TOKEN.getCode(), CodeEnum.GET_USERID_BY_TOKEN.getMessage());
            }
            //通过雪花算法生成课程ID
            long courseId = Long.parseLong(idGenerator.nextShortId(14));
            //创建对象
            Course course = new Course();
            course.setCourseId(courseId);
            course.setTeacherId(userIdFromToken);
            course.setTitle(courCreateRequest.getTitle());
            course.setCategoryId(courCreateRequest.getCategoryId());
            course.setCreateTime(new Date());
            course.setPrice(courCreateRequest.getPrice());
            course.setDetails(courCreateRequest.getDescription());
            int insert = courseMapper.insert(course);
            LogUtil.info(CourseService.class, "新增课程" + courseId);
            if (insert <= 0) {
                return BaseResult.error(CodeEnum.CREATE_COURSE_ERROR);
            }
            //处理标题图片（异步）
            if (courCreateRequest.getTitleImg() != null && !courCreateRequest.getTitleImg().isEmpty()) {
                MultipartFile titleImg = courCreateRequest.getTitleImg();
                BaseResult upload = ossFeign.upload(titleImg);
                if (upload.getCode() == 200) {
                    String titleUrl = (String) upload.getData();
                    //消息队列异步处理标题图片
                    // 保存标题图片信息到OssImage表
                    CourseImageMessage courseImageMessage = new CourseImageMessage();
                    courseImageMessage.setCourseId(courseId);
                    courseImageMessage.setUserId(userIdFromToken);
                    courseImageMessage.setImageUrl(titleUrl);
                    courseImageMessage.setRelationType("title");
                    courseImageMessage.setImageIndex(0);
                    rabbitTemplate.convertAndSend("course.exchange", "course.image", courseImageMessage);
                } else {
                    throw new BusException(CodeEnum.COURSE_TITLE_IMG_UPLOAD_ERROR.getCode(), CodeEnum.COURSE_TITLE_IMG_UPLOAD_ERROR.getMessage());
                }
            } else {
                throw new BusException(CodeEnum.UPDATE_COURSE_TITLE_IMAGE_ERROR.getCode(), CodeEnum.UPDATE_COURSE_TITLE_IMAGE_ERROR.getMessage());

            }

            //处理内容图片（异步）
            if (courCreateRequest.getContentImgs() != null && !courCreateRequest.getContentImgs().isEmpty()) {
                //拿出courCreateRequest中的contentImgs
                List<MultipartFile> contentImgs = courCreateRequest.getContentImgs();
                //使用CompletableFuture进行并行处理，允许以非阻塞的方式处理异步任务的结果。
                ArrayList<CompletableFuture<Void>> futures = new ArrayList<>();
                //遍历上传
                for (int i = 0; i < contentImgs.size(); i++) {
                    final int index = i + 1;
                    MultipartFile contentImg = contentImgs.get(i);
                    //忽略空文件
                    if (contentImg.isEmpty()) {
                        continue;
                    }
                    //创建异步任务上传
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        try {
                            BaseResult contentResult = ossFeign.upload(contentImg);
                            if (contentResult.getCode() == 200) {
                                String contentUrl = (String) contentResult.getData();
                                // 创建消息对象
                                CourseImageMessage message = new CourseImageMessage();
                                message.setCourseId(courseId);
                                message.setUserId(userIdFromToken);
                                message.setImageUrl(contentUrl);
                                message.setRelationType("content" + index);
                                message.setImageIndex(index);
                                rabbitTemplate.convertAndSend("course.exchange", "course.image", message);
                            } else {
                                LogUtil.warn(CourseService.class, "内容图片上传失败: index={" + index + "}, error={" + contentResult.getMessage() + "}");
                            }
                        } catch (Exception e) {
                            LogUtil.error(CourseService.class, "处理内容图片时发生错误: index={" + index + "}, error={" + e.getMessage() + "}" + e);
                        }

                    });
                    //将每个异步任务的 CompletableFuture 添加到列表中，方便后续统一管理。
                    futures.add(future);

                }
            }


            //处理课程安排数据
            List<TeacherScheduleDTO> scheduleDTOList = objectMapper.readValue(courCreateRequest.getSchedules(), new TypeReference<List<TeacherScheduleDTO>>() {
            });

            if (!scheduleDTOList.isEmpty()) {
                for (TeacherScheduleDTO teacherScheduleDTO : scheduleDTOList) {
                    TeacherSchedule teacherSchedule = new TeacherSchedule();
                    teacherSchedule.setTeacherId(userIdFromToken);
                    teacherSchedule.setCourseId(courseId);
                    // 设置上课日期
                    teacherSchedule.setDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getDate()));
                    teacherSchedule.setStartTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getStartTime()));
                    teacherSchedule.setEndTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getEndTime()));
                    teacherSchedule.setUpdatedTime(new Date());
                    teacherSchedule.setCreatedTime(new Date());
                    teacherSchedule.setRepeatType(teacherScheduleDTO.getRepeatType());
                    teacherSchedule.setStatus(0);
                    if (teacherScheduleDTO.getRepeatEndDate() != null) {
                        teacherSchedule.setRepeatEndDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getRepeatEndDate()));
                    }
                    userService.insertSchedule(teacherSchedule);
                    LogUtil.info(CourseService.class, "课程时间新增 = {" + teacherSchedule + "}");
                }
            } else {
                return BaseResult.error(CodeEnum.LESSON_NOT_NULL);
            }
            return BaseResult.ok("新增课程成功！", courseId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusException(CodeEnum.CREATE_COURSE_ERROR.getCode(), CodeEnum.CREATE_COURSE_ERROR.getMessage(), e + e.getMessage());
        }

    }

    @Override
    @LcnTransaction
    @Transactional
    public boolean delCourseService(String token, long courseId) {
        try {

            // 获取当前登录用户的Id
            Long userIdFromToken = userService.getUserIdFromToken(token);
            if (userIdFromToken == null) {
                throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
            }

            // 判断是否和传入的CourseId一致
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("course_id", courseId);
            Course course;
            try {
                course = courseMapper.selectOne(queryWrapper);
            } catch (Exception e) {
                throw new BusException(CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getCode(), CodeEnum.SELECT_COURSE_INFO_BY_ID_ERROR.getMessage());
            }

            if (course == null || !course.getTeacherId().equals(userIdFromToken)) {
                throw new BusException(CodeEnum.NO_AUTH_TO_CHANGE.getCode(), CodeEnum.NO_AUTH_TO_CHANGE.getMessage());
            }

            int delete;
            try {
                // 创建 UpdateWrapper 对象并设置条件
                UpdateWrapper<Course> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("course_id", courseId);
                // 设置 status 字段为 -1
                Course course1 = new Course();
                course1.setStatus(-1);
                delete = courseMapper.update(course1, queryWrapper);
                userService.updateScheduleStatusDel(courseId);
                if (delete <= 0) {
                    LogUtil.error(CourseService.class, "删除课程失败");
                    return false;
                }
            } catch (Exception e) {
                LogUtil.error(CourseService.class, "删除课程失败");
                return false;
            }

            // 删除图片库里相关的数据
            QueryWrapper<OssImage> ossImageQueryWrapper = new QueryWrapper<>();
            ossImageQueryWrapper.eq("user_id", userIdFromToken)
                    .and(wrapper -> wrapper.eq("relation_type", "title")
                            .or()
                            .eq("relation_type", "content1")
                            .or()
                            .eq("relation_type", "content2")
                            .or()
                            .eq("relation_type", "content3"));

            int delete1;
            try {
                delete1 = ossImageMapper.delete(ossImageQueryWrapper);
                if (delete1 < 0) {
                    LogUtil.error(CourseService.class, "删除相关图片失败");
                    return false;
                }
            } catch (Exception e) {
                LogUtil.error(CourseService.class, "删除相关图片失败");
                return false;
            }

            return true;
        } catch (Exception e) {
            LogUtil.error(CourseService.class, "发生未知错误: " + e.getMessage());
            return false;
        }
    }


    /* *
     * @Title: updateCourseService
     * @Author: vvSmile
     * @Date: 2025-03-21 19:32:24
     * @param token
     * @param courseId
     * @return boolean
     * @Description: TODO 修改课程信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @LcnTransaction
    public BaseResult updateCourseService(String token, CourCreateRequest courCreateRequest) throws JsonProcessingException {
        // 获取当前登录用户的Id
        Long userIdFromToken = userService.getUserIdFromToken(token);
        if (userIdFromToken == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        // 判断是否和传入的CourseId一致
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", courCreateRequest.getCourseId());
        Course course = courseMapper.selectOne(queryWrapper);
        if (course == null) {
            return BaseResult.error(CodeEnum.COURSE_IS_NULL);
        }
        if (!course.getTeacherId().equals(userIdFromToken)) {
            return BaseResult.error(CodeEnum.UPDATE_COURSE_ERROR);
        }
        // 新建updateWrapper对象
        UpdateWrapper<Course> courseUpdateWrapper = new UpdateWrapper<>();
        courseUpdateWrapper.eq("course_id", courCreateRequest.getCourseId());
        Course courseUpdate = new Course();
        if (courCreateRequest.getTitle() != null) {
            courseUpdate.setTitle(courCreateRequest.getTitle());
        }
        if (courCreateRequest.getCategoryId() != null) {
            courseUpdate.setCategoryId(courCreateRequest.getCategoryId());
        }
        if (courCreateRequest.getPrice() != null) {
            courseUpdate.setPrice(courCreateRequest.getPrice());
        }
        if (courCreateRequest.getDescription() != null) {
            courseUpdate.setDetails(courCreateRequest.getDescription());
        }
        int updateCourseInfo = courseMapper.update(courseUpdate, courseUpdateWrapper);
        // 处理课程安排数据
        if (courCreateRequest.getSchedules() != null) {
            // 同样为课程安排实现全量替换逻辑
            List<TeacherScheduleDTO> scheduleDTOList = objectMapper.readValue(
                    courCreateRequest.getSchedules(),
                    new TypeReference<List<TeacherScheduleDTO>>() {
                    }
            );
            // 如果传入的数据为空，直接返回错误
            if (scheduleDTOList.isEmpty()) {
                return BaseResult.error(CodeEnum.LESSON_NOT_NULL);
            }
            // 检查课程安排是否需要全量替换
            boolean replaceAllSchedules = scheduleDTOList.get(0).getReplaceAll() != null &&
                    scheduleDTOList.get(0).getReplaceAll();
            // 课程安排的全量替换逻辑
            if (replaceAllSchedules) {
                // 全量替换模式
                // 1. 删除该课程的所有现有记录
                int deleteAllSchedule = userService.deleteAllSchedule(courCreateRequest.getCourseId());
                LogUtil.info(CourseService.class, "删除课程安排记录：" + deleteAllSchedule + "条");
                // 2. 插入新的记录
                for (TeacherScheduleDTO teacherScheduleDTO : scheduleDTOList) {
                    TeacherSchedule teacherSchedule = new TeacherSchedule();
                    teacherSchedule.setTeacherId(userIdFromToken);
                    teacherSchedule.setCourseId(courCreateRequest.getCourseId());
                    teacherSchedule.setDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getDate()));
                    teacherSchedule.setStartTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getStartTime()));
                    teacherSchedule.setEndTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getEndTime()));
                    teacherSchedule.setUpdatedTime(new Date());
                    teacherSchedule.setCreatedTime(new Date());
                    teacherSchedule.setRepeatType(teacherScheduleDTO.getRepeatType());
                    teacherSchedule.setStatus(0);
                    // 全量替换模式下不传ID，确保插入新记录
                    teacherSchedule.setScheduleId(null);
                    if (!teacherScheduleDTO.getRepeatType().equals("once")) {
                        teacherSchedule.setRepeatEndDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getRepeatEndDate()));
                    }
                    userService.updateScheduleInfo(teacherSchedule);
                    LogUtil.info(CourseService.class, "课程时间新增 = {" + teacherSchedule + "}");
                }
            } else {
                // 增量更新模式
                for (TeacherScheduleDTO teacherScheduleDTO : scheduleDTOList) {
                    TeacherSchedule teacherSchedule = new TeacherSchedule();
                    teacherSchedule.setTeacherId(userIdFromToken);
                    teacherSchedule.setCourseId(courCreateRequest.getCourseId());
                    teacherSchedule.setDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getDate()));
                    teacherSchedule.setStartTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getStartTime()));
                    teacherSchedule.setEndTime(DateTimeUtils.parseDateTime(teacherScheduleDTO.getEndTime()));
                    teacherSchedule.setUpdatedTime(new Date());
                    teacherSchedule.setCreatedTime(new Date());
                    teacherSchedule.setRepeatType(teacherScheduleDTO.getRepeatType());
                    teacherSchedule.setStatus(0);
                    teacherSchedule.setScheduleId(teacherScheduleDTO.getScheduleId());
                    if (!teacherScheduleDTO.getRepeatType().equals("once")) {
                        teacherSchedule.setRepeatEndDate(DateTimeUtils.parseSimpleDate(teacherScheduleDTO.getRepeatEndDate()));
                    }
                    userService.updateScheduleInfo(teacherSchedule);
                    LogUtil.info(CourseService.class, "课程时间更新 = {" + teacherSchedule + "}");
                }
            }
        }
        if (updateCourseInfo > 0) {
            return BaseResult.ok("课程更新成功", updateCourseInfo);
        } else {
            return BaseResult.error(CodeEnum.UPDATE_COURSE_ERROR);
        }
    }

    /* *
     * @Title: updateCourseTitle
     * @Author: vvSmile
     * @Date: 2025-03-30 09:19:24
     * @param token
     * @param ossImage
     * @return boolean
     * @Description: TODO 更新课程图片
     */
    @Override
    @LcnTransaction
    @Transactional
    public String updateCourseImg(String token, Long courseId, String relationType, MultipartFile file) {
        // 获取当前登录用户的Id
        Long userIdFromToken = userService.getUserIdFromToken(token);
        if (userIdFromToken == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }

        BaseResult upload = ossFeign.upload(file);
        //查询oss是否存在
        QueryWrapper<OssImage> ossImageQueryWrapper = new QueryWrapper<>();
        ossImageQueryWrapper.eq("relation_type", relationType)
                .eq("course_id", courseId);
        OssImage ossImage1 = ossImageMapper.selectOne(ossImageQueryWrapper);
        if (ossImage1 == null) {
            OssImage ossImage = new OssImage();
            ossImage.setCourseId(courseId);
            ossImage.setUserId(userIdFromToken);
            ossImage.setUrl((String) upload.getData());
            ossImage.setRelationType(relationType);
            ossImage.setUploadTime(new Date());
            switch (relationType) {
                case "title":
                    ossImage.setDescription("课程标题图片");
                    break;
                case "content1":
                    ossImage.setDescription("课程内容图片1");
                    break;
                case "content2":
                    ossImage.setDescription("课程内容图片2");
                    break;
                case "content3":
                    ossImage.setDescription("课程内容图片3");
                    break;
                case "content4":
                    ossImage.setDescription("课程内容图片4");
                    break;
            }
            ossImageMapper.insert(ossImage);
        }
        //更新
        UpdateWrapper<OssImage> ossImageUpdateWrapper = new UpdateWrapper<>();
        ossImageUpdateWrapper
                .eq("relation_type", relationType)
                .eq("course_id", courseId);
        OssImage ossImage = new OssImage();
        ossImage.setUrl((String) upload.getData());
        int update = ossImageMapper.update(ossImage, ossImageUpdateWrapper);
        UpdateWrapper<Course> courseUpdateWrapper = new UpdateWrapper<>();
        courseUpdateWrapper
                .eq("course_id", courseId);
        Course course = new Course();
        switch (relationType) {
            case "title":
                course.setTitleImg((String) upload.getData());
                break;
            case "content1":
                course.setContent1Img((String) upload.getData());
                break;
            case "content2":
                course.setContent2Img((String) upload.getData());
                break;
            case "content3":
                course.setContent3Img((String) upload.getData());
                break;
            case "content4":
                course.setContent4Img((String) upload.getData());
                break;
        }

        int updateCourse = courseMapper.update(course, courseUpdateWrapper);
        if (update > 0 && updateCourse > 0) {
            return (String) upload.getData();
        }
        return "";
    }


    /* *
     * @Title: delCourseImg
     * @Author: vvSmile
     * @Date: 2025-03-30 14:21:47
     * @param token
     * @param courseId
     * @param relationType
     * @return Boolean
     * @Description: TODO 删除课程图片
     */
    @Override
    @LcnTransaction
    @Transactional
    public Boolean delCourseImg(String token, Long courseId, String relationType) {
        // 获取当前登录用户的Id
        Long userIdFromToken = userService.getUserIdFromToken(token);
        if (userIdFromToken == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //查询图片信息
        //查询oss是否存在
        QueryWrapper<OssImage> ossImageQueryWrapper = new QueryWrapper<>();
        ossImageQueryWrapper.eq("relation_type", relationType)
                .eq("course_id", courseId);
        OssImage ossImage = ossImageMapper.selectOne(ossImageQueryWrapper);
        //删除ossImage中的信息
        int delete = ossImageMapper.delete(ossImageQueryWrapper);
        //更新Course表
        UpdateWrapper<Course> courseUpdateWrapper = new UpdateWrapper<>();
        courseUpdateWrapper
                .eq("course_id", courseId);
        Course course = new Course();
        switch (relationType) {
            case "title":
                course.setTitleImg("");
                break;
            case "content1":
                course.setContent1Img("");
                break;
            case "content2":
                course.setContent2Img("");
                break;
            case "content3":
                course.setContent3Img("");
                break;
            case "content4":
                course.setContent4Img("");
                break;
        }
        int updateCourse = courseMapper.update(course, courseUpdateWrapper);
        //删除阿里云
        BaseResult delete1 = ossFeign.delete(ossImage.getUrl());
        return delete > 0 && updateCourse > 0;
    }


    /* *
     * @Title: getCourseTable
     * @Author: vvSmile
     * @Date: 2025-03-31 17:17:01
     * @param courseId
     * @return TeacherSchedule
     * @Description: TODO 获取课程表
     */
    @Override
    public List<TeacherSchedule> getCourseTable(Long courseId) {
        List<TeacherSchedule> teacherSchedules = userService.selectTeacherSchedules(courseId);
        if (teacherSchedules != null) {
            return teacherSchedules;
        }
        return null;
    }


    /* *
     * @Title: bookCourse
     * @Author: vvSmile
     * @Date: 2025-03-31 18:02:34
     * @param token
     * @param appointmentRequest
     * @return Boolean
     * @Description: TODO 预约课程
     */
    @Override
    @Transactional
    @LcnTransaction
    @TccTransaction
    public BaseResult bookCourse(String token, AppointmentRequestDTO request) {
        //1．验证学生身份
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //2．检查课程是否可预约
        TeacherSchedule schedule = userService.selectTeacherSchedulesByScheduleId(request.getScheduleId());
        if (schedule.getStatus() != 0) {
            return BaseResult.error(CodeEnum.COURSE_IS_NOT_AVAILABLE);
        }
        //分布式锁
        String lockKey = "Course:booking:" + schedule.getScheduleId();
        try {
            //3.发送消息
            redisDao.set(lockKey, "true", 10, TimeUnit.SECONDS);
            if (redisDao.get(lockKey) == null) {
                return BaseResult.error(CodeEnum.COURSE_IS_NOT_AVAILABLE);
            }
            //4．检查时间冲突
            Boolean check = checkTimeConflict(userId, request.getAppointmentDate(), request.getStartTime(), request.getEndTime());
            if (check == false) {
                throw new BusException(CodeEnum.COURSE_TIME_CONFLICT.getCode(), CodeEnum.COURSE_TIME_CONFLICT.getMessage());
            }
            //5.处理重复课程的情况
            //if (!schedule.getRepeatType().equals("once")){
            //    HandleRepeatCourseSchedule(schedule,request.getAppointmentDate());
            //}
            //更新课程状态
            if (!schedule.getRepeatType().equals("once")) {
                TeacherSchedule teacherSchedule = new TeacherSchedule();
                teacherSchedule.setTeacherId(schedule.getTeacherId());
                teacherSchedule.setCourseId(schedule.getCourseId());
                teacherSchedule.setDate(request.getAppointmentDate());
                teacherSchedule.setRepeatType("once");
                teacherSchedule.setCreatedTime(new Date());
                teacherSchedule.setUpdatedTime(new Date());
                teacherSchedule.setStatus(1);
                teacherSchedule.setStartTime(request.getStartTime());
                teacherSchedule.setEndTime(request.getEndTime());
                teacherSchedule.setUserId(userId);
                boolean insertSchedule = userService.insertSchedule(teacherSchedule);
                if (insertSchedule == false) {
                    return BaseResult.error(CodeEnum.UPDATE_SCHEDULE_STATUS_ERROR);
                }
            } else {
                TeacherSchedule teacherSchedule = new TeacherSchedule();
                teacherSchedule.setScheduleId(schedule.getScheduleId());
                teacherSchedule.setStatus(1);
                teacherSchedule.setStartTime(request.getStartTime());
                teacherSchedule.setEndTime(request.getEndTime());
                teacherSchedule.setUserId(userId);
                Boolean update = userService.updateScheduleStatusReverseBooking(teacherSchedule);
                if (!update) {
                    return BaseResult.error(CodeEnum.UPDATE_SCHEDULE_STATUS_ERROR);
                }
            }


            /**
             查询新增后的schedule_id
             */
            TeacherSchedule teacherSchedule = new TeacherSchedule();
            teacherSchedule.setTeacherId(schedule.getTeacherId());
            teacherSchedule.setCourseId(schedule.getCourseId());
            teacherSchedule.setDate(request.getAppointmentDate());
            teacherSchedule.setRepeatType("once");
            teacherSchedule.setCreatedTime(new Date());
            teacherSchedule.setUpdatedTime(new Date());
            teacherSchedule.setStatus(1);
            teacherSchedule.setStartTime(request.getStartTime());
            teacherSchedule.setEndTime(request.getEndTime());
            teacherSchedule.setUserId(userId);
            TeacherSchedule scheduleReturn = userService.selectTeacherSchedulesBySchedule(teacherSchedule);


            //6．创建预约记录
            CourseBooking courseBooking = new CourseBooking();
            courseBooking.setCourseId(schedule.getCourseId());
            courseBooking.setScheduleId(scheduleReturn.getScheduleId());
            courseBooking.setStudentId(userId);
            courseBooking.setTeacherId(scheduleReturn.getTeacherId());
            courseBooking.setBookingTime(request.getAppointmentDate());
            courseBooking.setClassDate(request.getAppointmentDate());
            courseBooking.setStartTime(request.getStartTime());
            courseBooking.setEndTime(request.getEndTime());
            courseBooking.setStatus(0);
            courseBooking.setCreatedTime(new Date());
            courseBooking.setUpdatedTime(new Date());
            //7．保存预约记录
            int insert = courseBookingMapper.insert(courseBooking);
            if (insert < 0) {
                return BaseResult.error(CodeEnum.CREATE_BOOKING_ERROR);
            }


            //预约成功创建订单表
            //通过雪花算法生成orderID
            String orderId = idGenerator.nextShortId(10);
            Orders orders = new Orders();
            orders.setOrdersId(orderId);
            orders.setUserId(userId);
            orders.setCourseId(schedule.getCourseId());
            orders.setCreateTime(new Date());
            orders.setScheduleId(scheduleReturn.getScheduleId());
            Boolean createOrder = orderFeign.createOrders(orders);
            //orderFeign.createOrder();
            //通知
            //采用RabbitMQ进行邮件或短信通知
            //定时任务处理预约结果

            return BaseResult.ok("预约成功", orders);
        } finally {
            //释放锁
            redisDao.del(lockKey);
        }

    }


    /* *
     * @Title: selectCourseInfoByScheduleId
     * @Author: vvSmile
     * @Date: 2025-04-01 11:05:46
     * @param scheduleId
     * @return Course
     * @Description: TODO 根据scheduleId查询课程信息
     */
    @Override
    public Course selectCourseInfoByScheduleId(String token, Long scheduleId) {
        //获取用户信息
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //获取teacher_schedule信息
        TeacherSchedule teacherSchedule = new TeacherSchedule();
        teacherSchedule.setScheduleId(scheduleId);
        teacherSchedule.setUserId(userId);
        TeacherSchedule schedule = userService.selectCourseIdByScheduleId(scheduleId);
        if (schedule != null) {
            QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
            courseQueryWrapper.eq("course_id", schedule.getCourseId());
            Course course1 = courseMapper.selectOne(courseQueryWrapper);
            List<TeacherSchedule> list1 = new ArrayList<>();
            list1.add(schedule);
            course1.setTeacherSchedule(list1);
            ;
            return course1;
        }
        return null;
    }

    /* *
     * @Title: cancelBookCourse
     * @Author: vvSmile
     * @Date: 2025-04-02 09:55:41
     * @param token
     * @param cancleRequestDTO
     * @return BaseResult
     * @Description: TODO 描述方法主要功能
     */
    @Override
    @TccTransaction
    @Transactional
    public BaseResult cancelBookCourse(String token, CancleRequestDTO cancleRequestDTO) {
        //获取用户信息
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //获取teacher_schedule信息
        TeacherSchedule teacherSchedule1 = new TeacherSchedule();
        teacherSchedule1.setScheduleId(cancleRequestDTO.getScheduleId());
        teacherSchedule1.setUserId(userId);
        teacherSchedule1.setDate(cancleRequestDTO.getAppointmentDate());
        TeacherSchedule teacherSchedule = userService.selectTeacherSchedulesByScheduleAndUserId(teacherSchedule1);
        if (teacherSchedule == null) {
            throw new BusException(CodeEnum.SCHEDULE_NOT_EXIST.getCode(), CodeEnum.SCHEDULE_NOT_EXIST.getMessage());
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(teacherSchedule.getDate());
        //检查CourseBooking记录是否存在
        QueryWrapper<CourseBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", cancleRequestDTO.getCourseId())
                .eq("schedule_id", teacherSchedule.getScheduleId())
                .eq("student_id", userId)
                .eq("class_date", formattedDate)
                .eq("status", 0);
        CourseBooking courseBooking = courseBookingMapper.selectOne(queryWrapper);
        if (courseBooking == null) {
            throw new BusException(CodeEnum.COURSE_BOOKING_NOT_EXIST.getCode(), CodeEnum.COURSE_BOOKING_NOT_EXIST.getMessage());
        }
        //取消CourseBooking记录
        courseBooking.setStatus(2);
        courseBooking.setCancelReason("支付超时");
        int up = courseBookingMapper.updateById(courseBooking);
        if (up < 0) {
            throw new BusException(CodeEnum.COURSE_BOOKING_UPDATE_ERROR.getCode(), CodeEnum.COURSE_BOOKING_UPDATE_ERROR.getMessage());
        }
        //查询Orders记录是否存在
        BaseResult ordersReturn = orderFeign.selectOrdersByOrdersId(cancleRequestDTO.getOrdersId());
        if (ordersReturn.getData() == null) {
            throw new BusException(CodeEnum.ORDERS_NOT_EXIST.getCode(), CodeEnum.ORDERS_NOT_EXIST.getMessage());
        }
        //取消Orders记录
        BaseResult cancelOrders = orderFeign.cancelOrders(cancleRequestDTO.getOrdersId());
        if (cancelOrders.getData() == null) {
            throw new BusException(CodeEnum.ORDERS_DELETE_ERROR.getCode(), CodeEnum.ORDERS_DELETE_ERROR.getMessage());
        }
        //删除schedule
        if (!teacherSchedule.getRepeatType().equals("once")) {
            return BaseResult.ok("取消预约失败！");
        }
        Boolean aBoolean = userService.delSchedule(teacherSchedule);
        if (!aBoolean) {
            throw new BusException(CodeEnum.ORDERS_DELETE_ERROR.getCode(), CodeEnum.ORDERS_DELETE_ERROR.getMessage());
        }
        return BaseResult.ok("取消预约成功", cancelOrders.getData());
    }


    /* *
     * @Title: selectCourseByUserId
     * @Author: vvSmile
     * @Date: 2025-04-04 12:48:14
     * @param token
     * @return List<Course>
     * @Description: TODO 查询用户已预约的课程
     */
    @Override
    public List<Course> selectCourseByUserId(String token) {
        //获取用户信息
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        //查询用户已预约的课程
        List<TeacherSchedule> teacherSchedules = userService.selectTeacherSchedulesByUserId(userId);
        ArrayList<Course> list = new ArrayList<>();
        if (teacherSchedules != null) {
            teacherSchedules.forEach(teacherSchedule -> {
                QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
                courseQueryWrapper.eq("course_id", teacherSchedule.getCourseId());
                Course course = courseMapper.selectOne(courseQueryWrapper);
                if (course != null) {
                    List<TeacherSchedule> list1 = new ArrayList<>();
                    list1.add(teacherSchedule);
                    course.setTeacherSchedule(list1);
                    list.add(course);
                }
            });
            return list;
        }
        return null;
    }


    /* *
     * @Title: updateBookingStatus
     * @Author: vvSmile
     * @Date: 2025-04-07 10:36:54
     * @param scheduleId
     * @param status
     * @return int
     * @Description: TODO 更新预约状态
     */
    @Override
    public int updateBookingStatus(Long scheduleId, int status) {
        UpdateWrapper<CourseBooking> courseBookingUpdateWrapper = new UpdateWrapper<>();
        courseBookingUpdateWrapper.eq("schedule_id", scheduleId)
                .set("status", status);
        int update = courseBookingMapper.update(null, courseBookingUpdateWrapper);
        return update;
    }

    @Override
    public CourseBooking selectBookingByScheduleIdAndCourseId(String token, Long scheduleId, Long courseId) {
        //获取用户信息
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        QueryWrapper<CourseBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("schedule_id", scheduleId)
                .eq("course_id", courseId)
                .eq("student_id", userId);
        CourseBooking courseBooking = courseBookingMapper.selectOne(queryWrapper);
        return courseBooking;
    }

    /* *
     * @Title: selectCourseByTeacherIdAIUsed
     * @Author: vvSmile
     * @Date: 2025-04-09 19:09:18
     * @param teacherId
     * @return List<Course>
     * @Description: TODO 根据教师id查询已预约的课程
     */
    @Override
    public List<Course> selectCourseByTeacherIdAIUsed(Long teacherId) {
        //创建QueryWrapper对象，配置查询条件
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //配置查询条件
        queryWrapper.eq("teacher_id", teacherId)
                .eq("status", 1);
        //调用mapper层查询所有课程
        List<Course> courses = courseMapper.selectList(queryWrapper);
        return courses;
    }

    @Override
    public List<Course> getHotCourses(int amount) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (amount > 0) {
            queryWrapper.orderByDesc("recommend_weight").last("limit " + amount);
            List<Course> courses = courseMapper.selectList(queryWrapper);
            return courses;
        }
        return null;
    }


    /* *
     * @Title: selectAllCourseList
     * @Author: vvSmile
     * @Date: 2025-04-11 14:02:50
     * @return List<Course>
     * @Description: TODO 查询所有课程
     */
    @Override
    public List<CourseDesc> selectAllCourseList() {
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.eq("status", 1);
        List<CourseDesc> courseDescs = courseMapper.selectCourseDesc();
        return courseDescs;
    }

    /* *
     * @Title: selectStudentCourseBookingByUserId
     * @Author: vvSmile
     * @Date: 2025-04-15 17:36:38
     * @param token
     * @return List<Course>
     * @Description: TODO 学生查询已预约的课程
     */
    @Override
    public List<CourseTableDTO> selectStudentCourseBookingByUserId(String token) {
        Long userId = userService.getUserIdFromToken(token);
        if (userId == null) {
            throw new BusException(CodeEnum.TOKEN_IS_NULL.getCode(), CodeEnum.TOKEN_IS_NULL.getMessage());
        }
        QueryWrapper<CourseBooking> courseBookingQueryWrapper = new QueryWrapper<>();
        courseBookingQueryWrapper.eq("student_id", userId)
                .and(wrapper -> wrapper.eq("status", 1)
                        .or()
                        .eq("status", 3)
                        .or()
                        .eq("status", 4));
        ArrayList<CourseTableDTO> courseTableDTOS = new ArrayList<>();
        for (CourseBooking courseBooking : courseBookingMapper.selectList(courseBookingQueryWrapper)) {
            QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
            courseQueryWrapper.eq("course_id", courseBooking.getCourseId());
            Course course = courseMapper.selectOne(courseQueryWrapper);
            CourseTableDTO courseTableDTO = new CourseTableDTO();
            courseTableDTO.setCourseName(course.getTitle());
            courseTableDTO.setDate(courseBooking.getClassDate());
            courseTableDTO.setStartTime(courseBooking.getStartTime());
            courseTableDTO.setEndTime(courseBooking.getEndTime());
            courseTableDTO.setStatus(courseBooking.getStatus());
            courseTableDTOS.add(courseTableDTO);
        }

        return courseTableDTOS;
    }

    @Override
    public int deleteCourseByTeacherId(Long userId) {
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.eq("teacher_id", userId);
        int delete = courseMapper.delete(courseQueryWrapper);
        //删除课程成功后，删除课程下的所有预约记录
        int delete1 = courseBookingMapper.delete(new QueryWrapper<CourseBooking>().eq("teacher_id", userId));
        if (delete > 0 && delete1 > 0) {
            return delete;
        }
        return 0;
    }

    @Override
    public PageUtils<BackCourseDTO> selectAllCourseServiceForBack(int currentPage, int pageSize, String courseName) {
        try {
            // 1. 查询总记录数
            QueryWrapper<Course> countWrapper = new QueryWrapper<>();
            countWrapper.eq("status", 1)
                    .or()
                    .eq("status", 0);
            long total = courseMapper.selectCount(countWrapper);

            // 2. 计算分页参数
            long offset = (currentPage - 1) * pageSize;

            // 3. 查询当前页数据
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            if (courseName != null) {
                queryWrapper.like("title", courseName);
            }
            queryWrapper.eq("status", 1)
                    .or()
                    .eq("status", 0)
                    .orderByDesc("create_time")  // 按创建时间倒序
                    .last("LIMIT " + offset + "," + pageSize);  // 使用MySQL的LIMIT语句
            ArrayList<BackCourseDTO> backCourseDTOS = new ArrayList<>();
            for (Course course : courseMapper.selectList(queryWrapper)) {
                BackCourseDTO backCourseDTO = new BackCourseDTO();
                backCourseDTO.setCourseId(String.valueOf(course.getCourseId()));
                backCourseDTO.setCourseName(course.getTitle());
                backCourseDTO.setCourseImg(course.getTitleImg());
                backCourseDTO.setTeacherName(userService.getUserInfoByTeacherId(course.getTeacherId()).getUserName());
                backCourseDTO.setPrice(course.getPrice());
                backCourseDTO.setStatus(course.getStatus());
                backCourseDTOS.add(backCourseDTO);
            }


            // 4. 构建分页对象
            return new PageUtils<BackCourseDTO>(backCourseDTOS, total, pageSize, currentPage);

        } catch (Exception e) {
            throw new BusException(
                    CodeEnum.SELECT_ALL_COURSES_PAGE_ERROR.getCode(),
                    "查询课程列表失败：" + e.getMessage()
            );
        }
    }

    @Override
    public BaseResult updateCoursePrice(Course course) {
        UpdateWrapper<Course> courseUpdateWrapper = new UpdateWrapper<>();
        courseUpdateWrapper.eq("course_id", course.getCourseId())
                .set("price", course.getPrice());
        int update = courseMapper.update(null, courseUpdateWrapper);
        return update > 0 ? BaseResult.ok() : BaseResult.error();
    }

    @Override
    public int updateCourseStatus(Course course) {
        int update = courseMapper.update(course,
                new UpdateWrapper<Course>()
                        .eq("course_id", course.getCourseId())
                        .set("status", course.getStatus()));
        if (update > 0) {
            return update;
        }
        return 0;
    }

    @Override
    public boolean delCourseForBack(long courseId) {
        try {
            // 判断是否和传入的CourseId一致
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("course_id", courseId);
            Course course = courseMapper.selectOne(queryWrapper);
            int delete;
            try {
                // 创建 UpdateWrapper 对象并设置条件
                UpdateWrapper<Course> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("course_id", courseId);
                // 设置 status 字段为 -1
                Course course1 = new Course();
                course1.setStatus(-1);
                delete = courseMapper.update(course1, queryWrapper);
                userService.updateScheduleStatusDel(courseId);
                if (delete <= 0) {
                    LogUtil.error(CourseService.class, "删除课程失败");
                    return false;
                }
            } catch (Exception e) {
                LogUtil.error(CourseService.class, "删除课程失败");
                return false;
            }

            // 删除图片库里相关的数据
            QueryWrapper<OssImage> ossImageQueryWrapper = new QueryWrapper<>();
            ossImageQueryWrapper.eq("user_id", course.getTeacherId())
                    .and(wrapper -> wrapper.eq("relation_type", "title")
                            .or()
                            .eq("relation_type", "content1")
                            .or()
                            .eq("relation_type", "content2")
                            .or()
                            .eq("relation_type", "content3"));

            int delete1;
            try {
                delete1 = ossImageMapper.delete(ossImageQueryWrapper);
                if (delete1 < 0) {
                    LogUtil.error(CourseService.class, "删除相关图片失败");
                    return false;
                }
            } catch (Exception e) {
                LogUtil.error(CourseService.class, "删除相关图片失败");
                return false;
            }

            return true;
        } catch (Exception e) {
            LogUtil.error(CourseService.class, "发生未知错误: " + e.getMessage());
            return false;
        }
    }

    @Override
    public BackCourseBoardDTO getCourseBoard() {
        //总课程数
        int totalCourses = courseMapper.selectCount(new QueryWrapper<Course>());
        //发布的课程
        int publishedCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("status", 1));
        int unpublishedCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("status", 0));
        int categoryOneCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 1));
        int categoryTwoCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 2));
        int categoryThreeCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 3));
        int categoryFourCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 4));
        int categoryFiveCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 5));
        int categorySixCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 6));
        int categorySevenCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 7));
        int categoryEightCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 8));
        int categoryNineCourses = courseMapper.selectCount(new QueryWrapper<Course>().eq("category_id", 9));
        BackCourseBoardDTO backCourseBoardDTO = new BackCourseBoardDTO();
        backCourseBoardDTO.setTotalCourses(totalCourses);
        backCourseBoardDTO.setPublishedCourses(publishedCourses);
        backCourseBoardDTO.setUnpublishedCourses(unpublishedCourses);
        backCourseBoardDTO.setCategoryOneCourses(categoryOneCourses);
        backCourseBoardDTO.setCategoryTwoCourses(categoryTwoCourses);
        backCourseBoardDTO.setCategoryThreeCourses(categoryThreeCourses);
        backCourseBoardDTO.setCategoryFourCourses(categoryFourCourses);
        backCourseBoardDTO.setCategoryFiveCourses(categoryFiveCourses);
        backCourseBoardDTO.setCategorySixCourses(categorySixCourses);
        backCourseBoardDTO.setCategorySevenCourses(categorySevenCourses);
        backCourseBoardDTO.setCategoryEightCourses(categoryEightCourses);
        backCourseBoardDTO.setCategoryNineCourses(categoryNineCourses);
        return backCourseBoardDTO;
    }


    //处理重复课程的预约
    private void HandleRepeatCourseSchedule(TeacherSchedule schedule, Date appointmentDate) {

    }


    //检查时间冲突
    private Boolean checkTimeConflict(Long userId, Date appointmentDate, Date startTime, Date endTime) {
        // 1. 检查学生在该时间段是否已有其他预约
        QueryWrapper<CourseBooking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id", userId)
                .eq("status", 1)
                .eq("booking_time", appointmentDate);
        List<CourseBooking> bookings = courseBookingMapper.selectList(queryWrapper);
        bookings.forEach(booking -> {
            if (booking.getStartTime().before(endTime) && booking.getEndTime().after(startTime)) {
                throw new BusException(CodeEnum.COURSE_TIME_CONFLICT.getCode(), CodeEnum.COURSE_TIME_CONFLICT.getMessage());
            }
        });
        return true;
    }


    //新增查询条件
    private OssImage queryOSSImage(long courseId, String relationType) {
        QueryWrapper<OssImage> ossImageQueryWrapper = new QueryWrapper<>();
        ossImageQueryWrapper.eq("course_id", courseId);
        ossImageQueryWrapper.eq("relation_type", relationType);
        return ossImageMapper.selectOne(ossImageQueryWrapper);
    }



}




